import os from 'os'
import path from 'path'
import { fileURLToPath } from 'url'
import fs from 'fs'
import { Msg, TranslateParams } from '../interface/common.interface.ts'
import { translate } from 'bing-translate-api'

// url 文件绝对路径
export const __filename = (url: string) => fileURLToPath(url)

// url 文件所在目录
export const __dirname = (url: string = import.meta.url) =>
  path.dirname(__filename(url))

// 本地目录 - 头像存放
export const PATH_AVATAR = path.join(
  __dirname(import.meta.url),
  '../upload/avatar/',
)

// 获取当前机器的ip地址(仅在 Windows 系统下生效)
export const getIpAddress = () => {
  const ifaces = os.networkInterfaces()
  let addressStr = ''
  for (const key in ifaces) {
    if (key && ifaces[key] && ifaces[key]!.length > 0) {
      for (let item of ifaces[key]!) {
        const { family, address, internal } = item
        if (
          key.includes('本地连接') &&
          family === 'IPv4' &&
          address !== '127.0.0.1' &&
          !internal
        ) {
          addressStr = address
          return addressStr
        }
      }
    }
  }
  return addressStr
}

/** 随机生成固定位数或者一定范围内的字符串数字组合
 * @param {Number} min 范围最小值
 * @param {Number} max 范围最大值，当不传递时表示生成指定位数的组合
 * @param {String} charStr指定的字符串中生成组合
 * @returns {String} 返回字符串结果
 * */
export const randomRange = (min: number, max: number, charStr?: string) => {
  let returnStr: string = '',
    range
  if (typeof max == 'string') {
    charStr = max
  }
  range =
    max && typeof max == 'number'
      ? Math.round(Math.random() * (max - min)) + min
      : min
  charStr =
    charStr || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  for (let i = 0; i < range; i++) {
    let index = Math.round(Math.random() * (charStr.length - 1))
    returnStr += charStr.substring(index, index + 1)
  }
  return returnStr
}

/**
 * 删除文件或目录
 * @param deletePath 要删除的文件或目录路径
 * @param recursive 删除目录时开启递归删除子目录
 * @returns
 */
export const deleteFile = (deletePath: string, recursive: boolean = false) => {
  return new Promise<void>(resolve => {
    if (fs.existsSync(deletePath)) {
      fs.rmSync(deletePath, {
        recursive,
        maxRetries: 1,
      })
    }
    resolve()
  })
}

/**
 * 检测字符串是否可以转换成对象
 * @param msg 任意字符串
 * @returns
 */
export const judgeParams = (msg: string) => {
  let data: Msg | string = ''
  try {
    data = JSON.parse(msg)
  } catch (error) {
    data = msg
  }
  return data
}

// 将驼峰格式的键转换为下划线格式
export const toSnakeCaseSingle = (field: string) => {
  let result: string = ''
  if (field) result = field.replace(/([A-Z])/g, '_$1').toLowerCase()
  return result
}

// 将驼峰格式的键转换为下划线格式(对象)
export const toSnakeCase = (obj: Record<string, any>) => {
  const result: Record<string, any> = {}
  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      const snakeCaseKey = toSnakeCaseSingle(key)
      result[snakeCaseKey] = obj[key]
    }
  }
  return result
}

// 将下划线格式的键转换为驼峰格式(对象)
export const toCamelCaseKeys = (obj: {
  [key: string]: any
}): { [key: string]: any } => {
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  const camelCaseObj: { [key: string]: any } = {}

  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      const camelCaseKey = key
        .split('_')
        .map((word, index) =>
          index === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1),
        )
        .join('')
      camelCaseObj[camelCaseKey] = toCamelCaseKeys(obj[key])
    }
  }

  return camelCaseObj
}

// 对更新和删除操作的返回结果进行处理
export const backResult = (res: number | number[]) => {
  // 更新结果处理
  if (Array.isArray(res)) {
    if (res[0] === 0) {
      throw new Error('数据不存在')
    } else {
      return res[0]
    }
  }
  // 删除结果处理
  if (res === 0) {
    throw new Error('数据不存在')
  } else {
    return res
  }
}

// 对象中带有下划线的键转化成驼峰格式(多个对象)
export const selectResultsHandle = (res: any[]) => {
  let result: any[] = []
  if (res && res.length) {
    result = res.map((item: any) => toCamelCaseKeys(item.dataValues))
    result.forEach((item: any) => {
      Object.keys(item).forEach((key: string) => {
        if (
          item[key] &&
          typeof item[key] === 'object' &&
          Object.prototype.hasOwnProperty.call(item[key], 'dataValues')
        ) {
          item[key] = item[key].dataValues
          item[key] = toCamelCaseKeys(item[key])
        }
      })
    })
  }
  return result
}

// 对象中带有下划线的键转化成驼峰格式(单个对象)
export const selectResultHandle = (res: any) => {
  let result: any = null
  if (res) {
    result = toCamelCaseKeys(res.dataValues)
  }
  return result
}

/**
 * 使用必应翻译API进行文本翻译
 *
 * @param {Object} params - 翻译参数对象
 * @param {string} [params.text=''] - 需要翻译的文本内容
 * @param {string} [params.to='zh'] - 目标语言代码，默认为中文
 *
 * @returns {Promise<string>} 翻译结果文本
 *
 * @description 该函数基于bing-translate-api库实现翻译功能，
 * 参数通过TranslateParams类型定义进行约束，返回值使用可选链操作符处理可能的undefined情况
 */
export const bingTranslate = async ({
  text = '',
  to = 'zh-Hans',
}: TranslateParams): Promise<string> => {
  try {
    const res = await translate(text, null, to)
    return res?.translation || ''
  } catch (err) {
    console.error('Translation error:', err)
    return Promise.reject(err)
  }
}
